﻿using System;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Interop;
using Microsoft.MapPoint.Rendering3D;
using Microsoft.MapPoint.Rendering3D.Utility;

namespace LaptopLoJack
{
	/// <summary>
	/// Interaction logic for Window1.xaml
	/// </summary>
	public partial class Window1 : Window
	{
        private static string LOCATION_LAYER = "Current Location";
        private static double DEFAULT_CAMERA_ALTITUDE = 10000;

        /// <summary>
        /// Constructor for the main LLJ WPF window
        /// </summary>
		public Window1()
		{
            //
            // Initialize the WPF elements
            //

			this.InitializeComponent();

            //
            // Request notification of when the globe control is ready
            //

            this.globeControl.Host.RenderEngine.Initialized += 
                new EventHandler(RenderEngine_Initialized);
		}

        /// <summary>
        /// Callback for notifying the main thread that a sensor (presumably
        /// the IP Geocoding one) has returned location information.
        /// 
        /// This is done asynchronously since the sensor may take a couple of 
        /// seconds, or more, to respond.
        /// </summary>
        /// <param name="loc"></param>
        private void _GeoLocationCallback(GeoHlpr.LljLocation loc)
        {
            //
            // Add a pushpin for the current location
            //

            this.globeControl.Host.Geometry.AddGeometry(new PushpinGeometry(
                LOCATION_LAYER,
                Guid.NewGuid().ToString(),
                LatLonAlt.CreateUsingDegrees(
                    loc.latitude,
                    loc.longitude,
                    0.0),
                PushpinInfo.Default));

            //
            // Set the Camera Position
            //

            LatLonAlt camLoc = LatLonAlt.CreateUsingDegrees(
                loc.latitude,
                loc.longitude,
                DEFAULT_CAMERA_ALTITUDE);

            this.globeControl.Host.Navigation.FlyTo(
                camLoc,
                -90, // directly down
                0);
        }

        /// <summary>
        /// Delegate type for notifying the main thread that the globe is
        /// ready.
        /// </summary>
        private delegate void RenderEngineInitializedCallbackDelegate();

        /// <summary>
        /// Callback for the main thread that the globe is ready
        /// </summary>
        private void _RenderEngineInitializedCallback()
        {
            //
            // Request user permission, if necessary, to obtain sensor 
            // information.
            //
            // This must be done on the main thread since it uses the window
            // handle.
            //

            GeoHlpr.RequestUserPermissionForSensorData(
                new WindowInteropHelper(
                    Application.Current.MainWindow).Handle);

            //
            // Get the current geographic location asynchronously
            //

            GeoHlpr.GeoLocationCallbackDelegate callback =
                new GeoHlpr.GeoLocationCallbackDelegate(_GeoLocationCallback);
            GeoHlpr.GetCurrentGeoLocation(callback);
        }

        /// <summary>
        /// Callback for receiving notification that the Virtual Earth 3D
        /// rendering engine is ready.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void RenderEngine_Initialized(object sender, EventArgs e)
        {
            //
            // Show details for elevation, texture, models, and buildings
            //

            this.globeControl.Host.DataSources.Add(
                new DataSourceLayerData(
                    "Elevation", 
                    "Elevation", 
                    @"http://sc1.maps.live.com//Manifests/HD.xml", 
                    DataSourceUsage.ElevationMap));
            
            this.globeControl.Host.DataSources.Add(
                new DataSourceLayerData(
                    "Texture", 
                    "Texture", 
                    @"http://sc1.maps.live.com//Manifests/HT.xml", 
                    DataSourceUsage.TextureMap));
            
            this.globeControl.Host.DataSources.Add(
                new DataSourceLayerData(
                    "Models", 
                    "Models", 
                    @"http://sc1.maps.live.com//Manifests/MO.xml", 
                    DataSourceUsage.Model));
            
            this.globeControl.Host.WorldEngine.ShowBuildingTextures = true;
            this.globeControl.Host.WorldEngine.ShowBuildings = true;

            //
            // Notify the main thread
            //

            RenderEngineInitializedCallbackDelegate callback = 
                new RenderEngineInitializedCallbackDelegate(
                    _RenderEngineInitializedCallback);
            this.Dispatcher.Invoke(callback, null);            
        }
	}
}